import { defineStore } from 'pinia'
import { getNoopActions, injectState, useRemote, useWorker, wrapSafeActions } from '@/controller/base/index'
import type { Worker } from '@/controller/base/types/worker'
import type { Remote } from '@/controller/base/types/remote'
import type { CoffeeMakerController } from '../CoffeeMaker/definition'
import { createCoffeeMakerState, CoffeeMakerGetters, CoffeeMakerActions } from '../CoffeeMaker/index'
import { DemoBaseActions, createDemoBaseState, setDemoBaseState } from './BaseAppliance'
import { merge } from 'lodash'
import { getDemoProgramActions, getDemoProgramGetters } from './common/Program'
import { useProgramEffects } from '../common/Program/program'
import type { DemoDatasource } from '@/demo/types'
import type { ProgramController } from '../common/Program/definition'

let demoDatasource!: DemoDatasource

export function useDemoCoffeeMakerControl(): CoffeeMakerController.Control {
  const createDemoCoffeeMakerState: () => CoffeeMakerController.State = () =>
    injectState(
      () => merge(createCoffeeMakerState(), createDemoBaseState()),
      (state) => {
        setDemoBaseState(state, demoDatasource)
      }
    )
  const DemoCoffeeMakerGetters: CoffeeMakerController.Getters = {
    ...(getDemoProgramGetters(CoffeeMakerGetters as ProgramController.Getters) as CoffeeMakerController.Getters),
  }
  const DemoCoffeeMakerActions: CoffeeMakerController.Actions = wrapSafeActions<
    CoffeeMakerController.Store,
    CoffeeMakerController.Actions
  >({
    ...merge(getNoopActions(CoffeeMakerActions), DemoBaseActions),
    ...getDemoProgramActions(demoDatasource),
  })
  const useDemoStore = defineStore<
    'DemoCoffeeMaker',
    CoffeeMakerController.State,
    CoffeeMakerController.Getters,
    CoffeeMakerController.Actions
  >('DemoCoffeeMaker', {
    state: createDemoCoffeeMakerState,
    getters: DemoCoffeeMakerGetters,
    actions: DemoCoffeeMakerActions,
  })

  const store = useDemoStore() as CoffeeMakerController.Store
  const worker = useWorker(store) as Worker.ApplianceWorker<CoffeeMakerController.Store>
  const remote = useRemote(store) as Remote.ApplianceRemote<CoffeeMakerController.Store>
  return { store, worker, remote }
}

export function createDemeoCoffeeMakerControl(datasource: DemoDatasource): CoffeeMakerController.Control {
  demoDatasource = datasource
  const control = useDemoCoffeeMakerControl()
  control.worker.init()
  useProgramEffects(control)
  return control
}
